home *** CD-ROM | disk | FTP | other *** search
- ; KISS-TNC-HEX-LOADER.MAC - KISS TNC Intel Hex Loader v0.3
- ; k3mc 8 Aug 86 v0.1
- ; 4 Oct 86 v0.2
- ; 18 Oct 86 v0.2a
- ; 18 Oct 86 v0.3
- ; v0.2 correctly sets the SP for either 16k or 32k of memory, and strips
- ; the parity bit from incoming chars.
- ; v0.2a allows 8k of RAM
- ; v0.3 try horrible hack to allow use w/o cutting JMP6
-
- .z80
- aseg
- org 4000h
-
- RAM equ 8000h ;Where the RAM begins
-
- ENQ equ 5h
- ACK equ 6h
- NAK equ 15h
- colon equ ':'
-
- rr_eof equ 1 ;Record Type for End of File / begin execution
-
-
- ; SIO equates
-
- SIO equ 0dch ;actually, only A5 is used for SIO -cs
-
- A_dat equ SIO+0 ;Modem port
- A_ctl equ SIO+1 ;Modem port
-
- B_dat equ SIO+2 ;user serial port
- B_ctl equ SIO+3 ;user serial port
-
- RR0_RXR equ 1 ;Receiver Char Avail bit
- RR0_TBE equ 4 ;TX Buffer Empty bit
-
-
-
- ;
- ; The general form of an Intel HEX record is as follows:
- ;
- ; :LLaaaaRRdddd..ddCC
- ;
- ; where LL is the number of bytes of data between RR and CC,
- ; not including RR or CC.
- ; aaaa is an address (see below),
- ; RR is a record type,
- ; dd are data bytes,
- ; and CC is a checksum, calculated as follows:
- ; CC = - ( LL + aaaa + RR + dd + dd + ... ( modulo 256 ) )
- ; That is, adding all the bytes LL to CC (inclusive), you should get zero.
- ;
- ; These are the record types needed:
- ; RR = 00 record type = data. aaaa is the load address for the data.
- ; RR = 01 record type = end of file.
- ; aaaa is the beginning execution address. LL is 00.
- ; :00aaaa01CC
- ; So, for example, if the start address is 8000, the last line of the file is
- ; :008000017F
- ;
- ; In this implementation, trailing checksums are ignored; you don't even have
- ; to include them.
- ;-----------------------------------------------------------------------------
- start:
- di ;for this test, NO INTERRUPTS!
-
- ; Figure out where top of stack is, set stack pointer.
- ; silly TNC-2 does not do complete address decoding for the RAMs if you are
- ; using only the two 8k x 8 chips. Hack to figure out top of memory so we can
- ; set stack pointer. This is REQUIRED by the KISS TNC.
- ; newer hack to see if we've only got 8k RAM (v0.2a)
-
- ld a,(9fffh) ;top of RAM if only 8K
- cpl
- ld b,a
- ld (9fffh),a
-
- ld a,(9fffh)
- cp b
- jp z,ok_8 ;we have at least 8k of RAM
-
- di
- halt ;else there is no RAM, so stop
-
- ok_8:
- ld a,(0bfffh)
- cpl
- ld b,a
- ld (0bfffh),a
-
- ld a,(0bfffh)
- cp b
- jp z,ok_16 ;we have at least 16k of RAM
-
- ld sp,0a000h
- jp stack_loaded ;else we only have 8k of RAM
-
- jp ok_16
-
- ; NOTE!!!! This is a horrible hack to allow automatic detection
- ;of the fact that JMP6 on TNC-2 has not been cut. This causes an RST 7 to
- ; happen, which we trap and go through a normal boot sequence... I TOLD you it
- ; was a hack! v0.3
-
- org 4038h
- jp 4000h ;force a boot if jumper not cut
-
- ok_16:
- ld a,55h ;one value
- ld (0bfffh),a
- ld a,0aah
- ld (0ffffh),a ;other value
-
- ld a,(0bfffh) ;get what should be 55h if 32k
-
- cp 55h
- ld sp,0
- jr z,stack_loaded ;if is 55h, then we've got 32 K, else 16 k
-
- ld sp,0c000h ;force stack value.
-
- stack_loaded:
-
- ;init SIO for async
-
- ld b,nb ;n bytes for init
- ld c,B_ctl ;to B port
- ld hl,binit ;with these bytes
- otir ;NOW!
-
- ld a,5
- out (A_ctl),a ;Ready WR5
- ld a,80h
- out (A_ctl),a ;turn off STATUS LED
-
- loop:
- call getchar ;returns char into A reg
- cp ENQ ;is it Control-E character?
- jr z,ENQCHR ;yes, deal with it
- cp colon
- jr z,saw_colon ;Go into Intel Hex download mode
- call putchar ;if neither, just echo it
- jr loop
-
- ENQCHR:
- ld hl,ENQ_string
- ENQ_loop:
- ld a,(hl)
- or a
- jr z,loop
- call putchar
- inc hl
- jr ENQ_loop
-
- saw_colon:
- call rdbyte
- ex af,af' ;save in other register set for a sec
- call rdbyte
- ld h,a
- call rdbyte
- ld l,a
- call rdbyte
- cp rr_eof ;is it record type 1 (begin execution)?
- jr nz,data_record ;no, it's just another data record
- ;else we give machine to downloaded program
- jp (hl) ;and go do it!
-
- data_record:
- ex af,af' ;get length value back
- ld b,a ;and ready loop index
- load_loop:
- call rdbyte
- ld (hl),a
- inc hl
- djnz load_loop ;load 'em up!
-
- ; Note, we ignore checksums completely
-
- find_colon:
- call getchar
- cp colon
- jr nz,find_colon ;spin for a colon
- jr saw_colon ;when we find colon, deal with next record
-
- ;*** Reads 2 characters from SIO, converts them to binary, and returns value
- ;*** into A reg. Disturbs no registers except AF.
- rdbyte:
- push bc
- call getchar
- call mk_binary
- rlca
- rlca
- rlca
- rlca
- ld b,a ;save hi part
- call getchar
- call mk_binary
- or b ;get hi + lo parts
- pop bc ;be tidy
- ret
-
- ;*** Convert the ASCII character into Binary character (src & dest is A reg)
- mk_binary:
- push hl
- push de
- call makeUC ;if anybody uses lower case, it's OK
- sub '0' ;convert ASCII -> binary (sorta)
- ld d,0
- ld e,a
- ld hl,btable ;base of translation table
- add hl,de ;produce pointer into table
- ld a,(hl) ;get corresponding binary
- pop de
- pop hl ;cleanliness is next to Godliness
- ret
-
- btable: defb 0,1,2,3,4,5,6,7,8,9,0,0,0,0,0,0,0,0ah,0bh,0ch,0dh,0eh,0fh
-
- ;*** If the character in A reg is lower case, this makes it upper case.
- makeUC:
- cp 'a'
- ret c ;if less than an 'a' we're done
- cp 'z'+1
- ret nc ;if > than 'z', not a letter, so we're done
- and 5fh ;else force to UPPER CASE
- ret
-
- ;*** Get a char from user TTY (Port B), no interrupt mode. Return it in A reg.
- getchar:
- in a,(B_ctl)
- and RR0_RXR
- jr z,getchar ;wait for a character to be typed
- in a,(B_dat)
- and 7fh ;strip parity bit (Phil's suggestion)
- ret
-
-
- ;*** Put a character to user TTY (Port B), no interrupts. Char is in A reg.
- putchar:
- push af ;we will need A
- ploop:
- in a,(B_ctl)
- and RR0_TBE
- jr z,ploop ;Wait for Transmitter buffer to become empty
-
- pop af
- out (B_dat),a
- ret
-
-
-
- binit: defb 1ah,0,14h,44h,3,0c3h,5,0eeh,11h,0 ;magic SIO inits
- bi_end equ $
- nb equ bi_end-binit ;Number of bytes in previous string
-
- ENQ_string:
- defb "KISS/Raw TNC Intel Hex Loader v0.3 18 Oct 86",13,10,0
-
- end start
-